package com.huarui.util;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.StringTokenizer;

public class DateParseUtil {
	/**
	 * 要想对日期进行格式化首先就需要一个DateFormat类的实例， 如果没有特殊需求的话，SimpleDateFormat类就是一个不错的选择，
	 * 它可以将日期类格式化为在其构造函数中指定的日期格式。 例如，如果我们想要将日期格式化为类似于2007-07-25这样的格式， 我们就可以如下定义
	 */
	static SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd");
	static SimpleDateFormat sFullFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	/**
	 * 下面的两个成员变量分别是日期分隔符字符串和字符串分隔器，专门用来解析字符串格式的日期
	 * 程序中主要的日期分隔符为"-"和"/"，且日期序列为“年/月/日”型，其内容缺一不可 例如:09/02/02或2009-02-02
	 */
	public static final String DATE_SEPARATOR = "-/: ";
	public static StringTokenizer sToken;

	// 1.1格式转换

	/** 将日期变为字符串格式  yyyy-MM-dd**/
	public static String format(GregorianCalendar pCal) {
		return sDateFormat.format(pCal.getTime());
	}
	/** 将日期变为字符串格式 yyyy-MM-dd **/
	public static String format(Date pDate) {
		return sDateFormat.format(pDate);
	}
	/** 将日期变为字符串格式  yyyy-MM-dd HH:mm:ss**/
	public static String fullFormat(Date pDate) {
		return sFullFormat.format(pDate);
	}

	/** 将字符串格式的日期转换为Calender **/
	public static GregorianCalendar parse2Cal(String pDateStr) {
		sToken = new StringTokenizer(pDateStr, DATE_SEPARATOR);
		int vYear = Integer.parseInt(sToken.nextToken());
		// GregorianCalendar的月份是从0开始算起的，变态！！
		int vMonth = Integer.parseInt(sToken.nextToken()) - 1;
		int vDayOfMonth = Integer.parseInt(sToken.nextToken());
		return new GregorianCalendar(vYear, vMonth, vDayOfMonth);
	}

	/** 将字符串类型的日期转换成Date(yyyy-MM-dd) **/
	public static Date parse2Date(String pDate) {
		try {
			return sDateFormat.parse(pDate);
		} catch (ParseException ex) {
			return null;
		}
	}
	
	/** 将字符串类型的日期转换成Date (yyyy-MM-dd HH:mm:ss) **/
	public static Date parse2FullDate(String pDate) {
		try {
			return sFullFormat.parse(pDate);
		} catch (ParseException ex) {
			return null;
		}
	}

	// 1.2.取得两个日期之间所差天数的方法
	/**
	 *返回未来的某一天和今天所差的日期数 注意，这里要clone一个新的日期以免对原始日期类造成的修改。
	 * 而在daysBetween(GregorianCalendarpFormer,GregorianCalendarpLatter)就
	 * 直接处理而不进行clone动作，因为这里已经做了:)
	 **/
	public static int daysBetween(GregorianCalendar pFurtherDay) {
		GregorianCalendar vToday = new GregorianCalendar();
		GregorianCalendar vFurtherDay = (GregorianCalendar) pFurtherDay.clone();
		return daysBetween(vToday, vFurtherDay);
	}

	/** 上面函数的String版本　 **/
	public static int daysBetween(String pFurtherDayStr) {
		GregorianCalendar vFurtherDay = DateParseUtil.parse2Cal(pFurtherDayStr);
		GregorianCalendar vToday = new GregorianCalendar();
		return daysBetween(vToday, vFurtherDay);
	}

	/** 返回较晚的时间(latter)与较早的时间(former)所差的天数 **/
	public static int daysBetween(String pFormerStr, String pLatterStr) {
		GregorianCalendar pFormer = DateParseUtil.parse2Cal(pFormerStr);
		GregorianCalendar pLatter = DateParseUtil.parse2Cal(pLatterStr);
		return daysBetween(pFormer, pLatter);
	}

	/** 返回较晚的时间(latter)与较早的时间(former)所差的天数 **/
	public static int daysBetween(GregorianCalendar pFormer,
			GregorianCalendar pLatter) {
		GregorianCalendar vFormer = pFormer, vLatter = pLatter;
		boolean vPositive = true;
		if (pFormer.before(pLatter)) {
			vFormer = pFormer;
			vLatter = pLatter;
		} else {
			vFormer = pLatter;
			vLatter = pFormer;
			vPositive = false;
		}

		vFormer.set(Calendar.MILLISECOND, 0);
		vFormer.set(Calendar.SECOND, 0);
		vFormer.set(Calendar.MINUTE, 0);
		vFormer.set(Calendar.HOUR_OF_DAY, 0);
		vLatter.set(Calendar.MILLISECOND, 0);
		vLatter.set(Calendar.SECOND, 0);
		vLatter.set(Calendar.MINUTE, 0);
		vLatter.set(Calendar.HOUR_OF_DAY, 0);

		int vCounter = 0;
		while (vFormer.before(vLatter)) {
			vFormer.add(Calendar.DATE, 1);
			vCounter++;
		}
		if (vPositive)
			return vCounter;
		else
			return -vCounter;
	}

	// 1.3.两个日期的月份差
	/** 本月和未来一个月的月份差 **/
	public static int monthsBetween(GregorianCalendar pFurtherMonth) {
		GregorianCalendar vToday = new GregorianCalendar();
		GregorianCalendar vFurtherMonth = (GregorianCalendar) pFurtherMonth
				.clone();
		return monthsBetween(vToday, vFurtherMonth);
	}

	/** 给定月分和本月的月份差 **/
	public static int monthsBetween(String pFurtherMonth) {
		GregorianCalendar vToday = new GregorianCalendar();
		GregorianCalendar vFurtherMonth = DateParseUtil.parse2Cal(pFurtherMonth);
		return monthsBetween(vToday, vFurtherMonth);
	}

	/** 给定两个时间相差的月份,String版 **/
	public static int monthsBetween(String pFormerStr, String pLatterStr) {
		GregorianCalendar vFormer = DateParseUtil.parse2Cal(pFormerStr);
		GregorianCalendar vLatter = DateParseUtil.parse2Cal(pLatterStr);
		return monthsBetween(vFormer, vLatter);
	}

	public static int monthsBetween(GregorianCalendar pFormer,
			GregorianCalendar pLatter) {
		GregorianCalendar vFormer = pFormer, vLatter = pLatter;
		boolean vPositive = true;
		if (pFormer.before(pLatter)) {
			vFormer = pFormer;
			vLatter = pLatter;
		} else {
			vFormer = pLatter;
			vLatter = pFormer;
			vPositive = false;
		}
		int vCounter = 0;
		while (vFormer.get(vFormer.YEAR) != vLatter.get(vLatter.YEAR)
				|| vFormer.get(vFormer.MONTH) != vLatter.get(vLatter.MONTH)) {
			vFormer.add(Calendar.MONTH, 1);
			vCounter++;
		}
		if (vPositive)
			return vCounter;
		else
			return -vCounter;
	}

	/** 返回今天是本月的第几天 **/
	public static int dayOfMonthOfToday() {
		GregorianCalendar vTodayCal = new GregorianCalendar();
		return vTodayCal.get(vTodayCal.DAY_OF_MONTH);
	}

	/** 返回本月是本年的第几个月 **/
	public static int monthOfYear() {
		GregorianCalendar vTodayCal = new GregorianCalendar();
		return vTodayCal.get(vTodayCal.MONTH) + 1;
	}

	// 返回给定日期的月份
	public static String getMonth(String pFormattedDate) {
		StringTokenizer vSt = new StringTokenizer(pFormattedDate, "-");
		vSt.nextToken();// 跳过年份
		int val = Integer.parseInt(vSt.nextToken());
		return val + "";
	}

	/** 获得从本月开始到本月+pZoneSize区间内的月数 **/
	public static String[] monthList(int pZoneSize) {
		String[] vMonthList = new String[pZoneSize];
		GregorianCalendar vTodayCal = new GregorianCalendar();
		for (int i = 0; i < pZoneSize; i++) {
			vMonthList[i] = String.valueOf(vTodayCal.get(vTodayCal.MONTH) + 1);
			vTodayCal.roll(vTodayCal.MONTH, true);
		}
		return vMonthList;
	}

	/** 仅显示小数点后两位的Formater **/
	public static DecimalFormat formatter = new DecimalFormat("####.##");

	/** 将给定的数字变成小数点后两位的字符串 **/
	public static String format(double pSrcVal) {
		return formatter.format(pSrcVal);
	}

}
